package com.matrix.async.core;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.matrix.async.bean.AsyncConfigurationBean;
import com.matrix.async.core.APPComponent;
import com.matrix.async.service.AsyncTaskService;
import com.matrix.async.dao.AsyncConfigurationDao;
import com.matrix.core.tools.LogUtil;
import com.matrix.core.tools.WebUtil;

/**
 * 异步任务服务类
 * @author Administrator
 *
 */
@Component
public class InitAsync {
	@Autowired
	AsyncTaskService asyncTaskService;
	@Autowired
	private AsyncConfigurationDao asyncConfigurationDao;
	
	@Value("${async.useExceptionHandler}")
	private String useExceptionHandler;

	Class<?> exceptionHandler;
	Class<?> taskQueue;
	Class<?> comsumer;
	Class<?> producer;

	Map<String, Object> taskQueueMap = new HashMap<String, Object>();
	Map<String, Object> comsumerMap = new HashMap<String, Object>();
	Map<String, Object> producerMap = new HashMap<String, Object>();

	public InitAsync() throws ClassNotFoundException {
		super();
		exceptionHandler = Class.forName("com.matrix.async.core.ExceptionHandlerFactoryBean");
		taskQueue = Class.forName("com.matrix.async.core.TaskQueueFactoryBean");
		comsumer = Class.forName("com.matrix.async.core.ComsumerFactoryBean");
		producer = Class.forName("com.matrix.async.core.ProducerFactoryBean");
	}

	/**
	 * 初始化异步任务
	 * @param list
	 * @throws ClassNotFoundException
	 */
	public void generateAsyncBean(List<APPComponent> list) throws ClassNotFoundException {
        
		// 生成ExceptionHandler对象 
		// 需要判断是自动添加清理
		if("true".equals(useExceptionHandler)) {
			LogUtil.info("开启清理长期未处理任务");
			// 判断容器中是否已存在
			if(!WebUtil.getApplicationContext().containsBean("exceptionHandler")) {
				ExtendWebUtil.setBean("exceptionHandler", exceptionHandler, new HashMap<String, Object>());
				list.add((APPComponent) WebUtil.getBean("exceptionHandler"));
			}
		}

		List<AsyncConfigurationBean> selectTotal = asyncConfigurationDao.selectTotal();
		for (int i = 0; i < selectTotal.size(); i++) {
			taskQueueMap.clear();
			comsumerMap.clear();
			producerMap.clear();
         
			String handlerName = "handler" + selectTotal.get(i).getId();
			// 当容器中没有该对象才加入
			if(!WebUtil.getApplicationContext().containsBean(handlerName)) {
				// 生成Handler对象
				ExtendWebUtil.setBean("handler" + selectTotal.get(i).getId(),
						Class.forName(selectTotal.get(i).getHandler()), new HashMap<String, Object>());
				
				// 生成TaskQueue对象
				taskQueueMap.put("taskType", selectTotal.get(i).getTaskType());
				ExtendWebUtil.setBean("taskQueue" + selectTotal.get(i).getId(), taskQueue, taskQueueMap);
				
				// 生成Comsumer对象
				comsumerMap.put("taskType", selectTotal.get(i).getTaskType());
				comsumerMap.put("taskQueue", WebUtil.getBean("taskQueue" + selectTotal.get(i).getId()));
				comsumerMap.put("startupDelay", selectTotal.get(i).getStartupDelay());
				comsumerMap.put("beanUse", selectTotal.get(i).getBeanUse());
				ExtendWebUtil.setBean("comsumer" + selectTotal.get(i).getId(), comsumer, comsumerMap);
				
				// 生成Producer对象
				producerMap.put("taskType", selectTotal.get(i).getTaskType());
				producerMap.put("taskQueue", WebUtil.getBean("taskQueue" + selectTotal.get(i).getId()));
				producerMap.put("taskHandler", WebUtil.getBean("handler" + selectTotal.get(i).getId()));
				producerMap.put("batchSize", selectTotal.get(i).getBatchSize());
				producerMap.put("startupDelay", selectTotal.get(i).getStartupDelay());
				producerMap.put("beanUse", selectTotal.get(i).getBeanUse());
				ExtendWebUtil.setBean("producer" + selectTotal.get(i).getId(), producer, producerMap);
				if (selectTotal.get(i).getAppFactoryBean().equals("true")) {
					list.add((APPComponent) WebUtil.getBean("taskQueue" + selectTotal.get(i).getId()));
					list.add((APPComponent) WebUtil.getBean("comsumer" + selectTotal.get(i).getId()));
					list.add((APPComponent) WebUtil.getBean("producer" + selectTotal.get(i).getId()));
				}
			}
		}

	}

	/**
	 * 添加异步任务
	 * @param asyncConfigurationBean
	 * @param componentList
	 * @throws ClassNotFoundException
	 */
	public void addAsyncBean(AsyncConfigurationBean asyncConfigurationBean, List<APPComponent> componentList)
			throws ClassNotFoundException {
		// 生成Handler对象
		if (WebUtil.getApplicationContext().containsBean("handler" + asyncConfigurationBean.getId())) {
			ExtendWebUtil.removeBean("handler" + asyncConfigurationBean.getId());
		}
		ExtendWebUtil.setBean("handler" + asyncConfigurationBean.getId(),
				Class.forName(asyncConfigurationBean.getHandler()), new HashMap<String, Object>());

		// 生成TaskQueue对象
		if (WebUtil.getApplicationContext().containsBean("taskQueue" + asyncConfigurationBean.getId())) {
			ExtendWebUtil.removeBean("taskQueue" + asyncConfigurationBean.getId());
		}
		taskQueueMap.put("taskType", asyncConfigurationBean.getTaskType());
		ExtendWebUtil.setBean("taskQueue" + asyncConfigurationBean.getId(), taskQueue, taskQueueMap);

		// 生成Comsumer对象
		if (WebUtil.getApplicationContext().containsBean("comsumer" + asyncConfigurationBean.getId())) {
			ExtendWebUtil.removeBean("comsumer" + asyncConfigurationBean.getId());
		}
		comsumerMap.put("taskType", asyncConfigurationBean.getTaskType());
		comsumerMap.put("taskQueue", WebUtil.getBean("taskQueue" + asyncConfigurationBean.getId()));
		comsumerMap.put("startupDelay", asyncConfigurationBean.getStartupDelay());
		comsumerMap.put("beanUse", asyncConfigurationBean.getBeanUse());
		ExtendWebUtil.setBean("comsumer" + asyncConfigurationBean.getId(), comsumer, comsumerMap);

		// 生成Producer对象
		if (WebUtil.getApplicationContext().containsBean("producer" + asyncConfigurationBean.getId())) {
			ExtendWebUtil.removeBean("producer" + asyncConfigurationBean.getId());
		}
		producerMap.put("taskType", asyncConfigurationBean.getTaskType());
		producerMap.put("taskQueue", WebUtil.getBean("taskQueue" + asyncConfigurationBean.getId()));
		producerMap.put("taskHandler", WebUtil.getBean("handler" + asyncConfigurationBean.getId()));
		producerMap.put("batchSize", asyncConfigurationBean.getBatchSize());
		producerMap.put("startupDelay", asyncConfigurationBean.getStartupDelay());
		producerMap.put("beanUse", asyncConfigurationBean.getBeanUse());
		ExtendWebUtil.setBean("producer" + asyncConfigurationBean.getId(), producer, producerMap);

		if (asyncConfigurationBean.getAppFactoryBean().equals("true")) {
			componentList.add((APPComponent) WebUtil.getBean("taskQueue" + asyncConfigurationBean.getId()));
			componentList.add((APPComponent) WebUtil.getBean("comsumer" + asyncConfigurationBean.getId()));
			componentList.add((APPComponent) WebUtil.getBean("producer" + asyncConfigurationBean.getId()));
		}
	}
}
